/*
 * directives.c -- part of ZilUtils/ZilAsm
 *
 * Copyright (C) 2016 Jason Self <j@jxself.org>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 *
 * SPDX-License-Identifier: AGPL-3.0-or-later
 */

#include <stdlib.h>   /* bsearch */
#include <string.h>   /* strcmp */

#include "directives.h"

#define ARRAY_SIZE(x)  ((sizeof(x)) / (sizeof(x[0])))

static int byte_handler(const char *args)
{
	/* !!! TODO !!! */
	return 0;
}

static int end_handler(const char *args)
{
	/* !!! TODO !!! */
	return 0;
}

static int endi_handler(const char *args)
{
	/* !!! TODO !!! */
	return 0;
}

static int endt_handler(const char *args)
{
	/* !!! TODO !!! */
	return 0;
}

static int fstr_handler(const char *args)
{
	/* !!! TODO !!! */
	return 0;
}

static int funct_handler(const char *args)
{
	/* !!! TODO !!! */
	return 0;
}

static int gstr_handler(const char *args)
{
	/* !!! TODO !!! */
	return 0;
}

static int gvar_handler(const char *args)
{
	/* !!! TODO !!! */
	return 0;
}

static int insert_handler(const char *args)
{
	/* !!! TODO !!! */
	return 0;
}

static int len_handler(const char *args)
{
	/* !!! TODO !!! */
	return 0;
}

static int new_handler(const char *args)
{
	/* !!! TODO !!! */
	return 0;
}

static int object_handler(const char *args)
{
	/* !!! TODO !!! */
	return 0;
}

static int prop_handler(const char *args)
{
	/* !!! TODO !!! */
	return 0;
}

static int str_handler(const char *args)
{
	/* !!! TODO !!! */
	return 0;
}

static int strl_handler(const char *args)
{
	/* !!! TODO !!! */
	return 0;
}

static int table_handler(const char *args)
{
	/* !!! TODO !!! */
	return 0;
}

static int vocbeg_handler(const char *args)
{
	/* !!! TODO !!! */
	return 0;
}

static int vocend_handler(const char *args)
{
	/* !!! TODO !!! */
	return 0;
}

static int word_handler(const char *args)
{
	/* !!! TODO !!! */
	return 0;
}

static int zword_handler(const char *args)
{
	/* !!! TODO !!! */
	return 0;
}

// Sorted array
static Directive Directives[] = {
	"BYTE",      byte_handler,
	"END",        end_handler,
	"ENDI",      endi_handler,
	"ENDT",      endt_handler,
	"FSTR",      fstr_handler,
	"FUNCT",    funct_handler,
	"GSTR",      gstr_handler,
	"GVAR",      gvar_handler,
	"INSERT",  insert_handler,
	"LEN",        len_handler,
	"NEW",        new_handler,
	"OBJECT",  object_handler,
	"PROP",      prop_handler,
	"STR",        str_handler,
	"STRL",      strl_handler,
	"TABLE",    table_handler,
	"VOCBEG",  vocbeg_handler,
	"VOCEND",  vocend_handler,
	"WORD",      word_handler,
	"ZWORD",    zword_handler
};

typedef struct {
	const char *contents;
	unsigned length;
} Name;

static int namecmp(const void *key, const void *elem)
{
	const Name      *p = (Name     *)key;
	const Directive *d = (Directive*)elem;

	int len1 = p->length;
	int len2 = strlen(d->name);

	int rc = memcmp(p->contents, elem, len1 < len2 ? len1 : len2);
	return rc ? rc : (len1 - len2);
}

Directive_handler directive_lookup(const char *name, unsigned namelen)
{
	Name n = { name, namelen };
	Directive *p = (Directive*)bsearch(&n, Directives, ARRAY_SIZE(Directives), sizeof(Directive), namecmp);
	return p ? p->handler : NULL;
}
